""" 时间转换的一个封装，方便按照设置好的格式进行时间转化 """
import time
import datetime


class MyTime:
    """
    封装时间转化
    @attr
        : timestamp: 当前时间戳
        ：timestr: 当前时间字符串
        ：datematter: 时间格式'%Y-%m-%d %H:%M:%S.%f'
    """
    acc = 0  # 默认保留时间后面三位小数，即毫秒
    datematter = '%Y-%m-%d %H:%M:%S'

    def __init__(self, type=1) -> None:
        """
        @param:
            type: 时间戳/时间格式的类型。0： 10位时间戳和秒级时间格式。  1： 13位时间戳和毫秒级时间格式。
        """
        if type == 0:
            self.__class__.acc = 0
            self.__class__.datematter = '%Y-%m-%d %H:%M:%S'
        else:
            self.__class__.acc = 3
            self.__class__.datematter = '%Y-%m-%d %H:%M:%S.%f'
        self.timestamp = int(round(time.time() * pow(10, self.__class__.acc)))
        self.timestr = datetime.datetime.now().strftime(self.__class__.datematter)

    @staticmethod
    def timestamp(len=10):
        """
        获取当前时间戳
        @param:
            len: 时间戳的位数，10位或者13位，默认为10位
        """
        return int(round(time.time() * pow(10, len - 10)))

    @staticmethod
    def timestr(dt:datetime.datetime = None, format='%Y-%m-%d %H:%M:%S'):
        """
        获取当前时间字符串
        @param:
            format: 时间格式 默认：'%Y-%m-%d %H:%M:%S'
        """
        if dt:
            return dt.strftime(format)
        return datetime.datetime.now().strftime(format)

    @staticmethod
    def datetime():
        """
        获取当前时间datetime
        """
        return datetime.datetime.now()

    @staticmethod
    def datetime_add(dt, days=0, seconds=0, minutes=0, hours=0, weeks=0):
        """
        datetime加减
        :dt 
        """
        if isinstance(dt,str):
            dt = datetime.datetime.strptime(dt, MyTime.datematter)
        return dt + datetime.timedelta(days=days, seconds=seconds, minutes=minutes, hours=hours, weeks=weeks)

    @staticmethod
    def timestrfrom(timestamp, isstrict=False):
        """
        将时间戳转换成字符串时间
        @param:
            timestamp: 时间戳，不限位数
            isstarict: 是否严格输出指定位数时间字符串。True的时候，按照MyTime.acc的位数输出时间字符串；false的时候，按照时间戳的位数输出对应位数的时间字符串；
        """
        mi = pow(10, max(len(str(int(timestamp))) - 10, 0))
        if (mi == 1 and not isstrict) or (isstrict and MyTime.acc == 0):  # 如果是秒级，直接格式化输出
            # time类不支持f%,所以不能直接格式化为毫秒
            return time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(timestamp) / mi))
        microseconds = str(timestamp)[10:]  # 获取毫秒时间
        if isstrict:
            microseconds = (microseconds + '000000000')[:MyTime.acc]
        return time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(timestamp / mi)) + '.{}'.format(microseconds)

    @staticmethod
    def timestampfrom(tstr: str, len=10):
        """
        将时间字符串转化成时间戳
        @param:
            tstr: 字符串时间
            len: 时间戳的位数，10位或者13位，默认为10位,指定-1时，返回字符串时间的位数
        """
        index = tstr.find('.')
        timestr = tstr if index == -1 else tstr[:index]
        microseconds = '' if index == -1 else tstr[index + 1:]
        # microseconds = (microseconds + '0000000000000')
        time_obj = time.strptime(timestr, '%Y-%m-%d %H:%M:%S')
        stamp = str(int(time.mktime(time_obj))) + microseconds
        if len > 0:
            stamp = stamp[:len]
        return stamp

    @staticmethod
    def get_date_part(partname, tstr=None):
        """
        获取日期的某一部分
        @param:
            partname: 需要获取的日期部分, 可以是：YY/year, MM/month, DD/day, HH/hour, mm/minute, ss/second
            tstr: 时间戳或者时间字符串，为none时，获取的日期是当天的日期
        """
        timeobj = None
        if not tstr:
            timeobj = datetime.datetime.now()
        else:
            tstr = str(tstr)
            try:
                float(tstr)  # 用trycatch检测这个字符串是否是时间戳
                timestr = MyTime.timestrfrom(tstr[:10])  # 截取秒级时间戳进行转化
                timeobj = datetime.datetime.strptime(
                    timestr, '%Y-%m-%d %H:%M:%S')
            except ValueError:
                timestr = tstr if tstr.find(
                    '.') == -1 else tstr[:tstr.find('.')]
                timeobj = datetime.datetime.strptime(
                    timestr, '%Y-%m-%d %H:%M:%S')
        if partname == 'YY' or partname == 'year':
            return timeobj.year
        elif partname == 'month' or partname == 'MM':
            return timeobj.month
        elif partname == 'day' or partname == 'DD':
            return timeobj.day
        elif partname == 'hour' or partname == 'HH':
            return timeobj.hour
        elif partname == 'minute' or partname == 'mm':
            return timeobj.minute
        elif partname == 'second' or partname == 'ss':
            return timeobj.second
        else:
            return timeobj


    @staticmethod
    def getDate(tstr=None, type=0):
        """
        获取日期时间
        @param:
            tstr: 时间戳或者时间字符串，为none时，获取的日期是当天的日期
            type: 日期时间中间的连接符。0:标准的‘-’；1：常用的'/'; 2: 常用的''（无连接符）
        """
        timeobj = None
        if not tstr:
            timeobj = datetime.datetime.now()
        else:
            tstr = str(tstr)
            try:
                float(tstr)  # 用trycatch检测这个字符串是否是时间戳
                timestr = MyTime.timestrfrom(tstr[:10])  # 截取秒级时间戳进行转化
                timeobj = datetime.datetime.strptime(
                    timestr, '%Y-%m-%d %H:%M:%S')
            except ValueError:
                timestr = tstr if tstr.find(
                    '.') == -1 else tstr[:tstr.find('.')]
                timeobj = datetime.datetime.strptime(
                    timestr, '%Y-%m-%d %H:%M:%S')
        if type == 0:
            return timeobj.strftime('%F')
        elif type == 1:
            return timeobj.strftime('%Y/%m/%d')
        elif type == 2:
            return timeobj.strftime('%Y%m%d')
        else:
            return timeobj


if __name__ == '__main__':
    print(MyTime.timestamp())
    print(MyTime.timestr())
    print(MyTime(0).timestr)
    print(MyTime(0).timestamp)
    print(MyTime.get_date_part('MM'))
